package cn.anecansaitin.whimsy.common.network;

import cn.anecansaitin.whimsy.Whimsy;
import cn.anecansaitin.whimsy.common.block.entity.ISimpleBlockEntitySynchronized;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.neoforge.network.handling.PlayPayloadContext;

public record SimpleBlockEntityPack(BlockPos pos, ResourceLocation entityType, Tag tag) implements CustomPacketPayload {
    public static final ResourceLocation ID = Whimsy.resource("simple_block_entity_pack");
    public static final ClientHandler HANDLER = new ClientHandler();

    public SimpleBlockEntityPack(FriendlyByteBuf buffer) {
        this(buffer.readBlockPos(), buffer.readResourceLocation(), buffer.readNbt());
    }

    @Override
    public void write(FriendlyByteBuf friendlyByteBuf) {
        friendlyByteBuf.writeBlockPos(pos);
        friendlyByteBuf.writeResourceLocation(entityType);
        friendlyByteBuf.writeNbt(tag);
    }

    @Override
    public ResourceLocation id() {
        return ID;
    }

    public static class ClientHandler {
        private ClientHandler(){}

        public void handle(SimpleBlockEntityPack data, PlayPayloadContext context) {
            context.workHandler().submitAsync(() -> {
                ClientLevel level = Minecraft.getInstance().level;
                BlockPos pos = data.pos;

                if (!level.isLoaded(pos)) {
                    return;
                }

                BlockEntity entity = level.getBlockEntity(pos);

                if (entity == null || !BlockEntityType.getKey(entity.getType()).equals(data.entityType) || !(entity instanceof ISimpleBlockEntitySynchronized synchronize)) {
                    return;
                }

                synchronize.dataFromServer(data.tag);
            });
        }
    }
}
